package com.haoshuang.zhouzhoubang.utils.oss;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.DeleteObjectRequest;
import com.alibaba.sdk.android.oss.model.DeleteObjectResult;
import com.alibaba.sdk.android.oss.model.ObjectMetadata;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.Random;


/**
 * Copyright (c) 山东六牛网络科技有限公司 https://liuniukeji.com
 *
 * @Description OSS操作类
 * @Author 田志浩 QQ: 1126201641
 * @Copyright Copyright (c) 山东六牛网络科技有限公司 保留所有版权(https://www.liuniukeji.com)
 * @Date 2018/6/12
 * @CreateBy Android Studio
 */
public class OSSUtils {
    private static OSS oss;
    private static OSSUtils utils;
    public static final String endpoint = "http://oss-cn-hangzhou.aliyuncs.com/";  //上传用
    private static final String accessKeyId = "LTAI5tGWYXa8KcyYmhoj2BTW";
    private static final String accessKeySecret = "wpcIAJBBIyYec0XJnsxlwQMTOTjm83";
    private static final String testBucket = "jialubao";    // 存储空间名称
    private static String ossObjectKey;

    //视频第一帧后缀
    public static final String videoUrlSuffix = "?x-oss-process=video/snapshot,t_1000,m_fast,ar_auto";

    public static OSSUtils newInstance(Context context) {

        ossObjectKey = "android/test/";

        if (null == utils) {
            utils = new OSSUtils();
        }
        if (null == oss) {
            OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(accessKeyId, accessKeySecret);
            ClientConfiguration conf = new ClientConfiguration();
            conf.setConnectionTimeout(150 * 1000); // 连接超时，默认15秒
            conf.setSocketTimeout(150 * 1000); // socket超时，默认15秒
            conf.setMaxConcurrentRequest(5); // 最大并发请求书，默认5个
            conf.setMaxErrorRetry(2); // 失败后最大重试次数，默认2次
            OSSLog.enableLog();
            oss = new OSSClient(context, endpoint, credentialProvider, conf);
        }
        return utils;
    }

    /**有回调状态的单张图片上传功能
     * @param  uploadObject 上传图片存放的oss文件夹路径
     * @param  uploadFilePath 图片在手机的存放路径
     * @param  progressCallback 上传到oss的成功，失败，进行中的方法回调
     * */
    public void putObjectMethod(final String uploadObject, final String uploadFilePath, final ProgressCallback<PutObjectRequest, PutObjectResult> progressCallback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                asyncPutObjectFromLocalFile(ossObjectKey + uploadObject, uploadFilePath, progressCallback);
            }
        }).start();
    }
    /**有回调状态的多张图片上传功能 position表示上传的位置
     * @param  uploadObject 上传图片存放的oss文件夹路径
     * @param  uploadFilePath 图片在手机的存放路径
     * @param  position 上传图片存放的oss文件夹路径内的位置
     * @param  progressCallback 上传到oss的成功，失败，进行中的方法回调
     * */
    public void putObjectMethod2(final String uploadObject, final String uploadFilePath, final int position, final ProgressCallback2<PutObjectRequest, PutObjectResult> progressCallback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                asyncPutObjectFromLocalFile2(ossObjectKey + uploadObject, uploadFilePath, position, progressCallback);
            }
        }).start();
    }

    //有回调状态的删除功能
    public void delObjectMethod(final String uploadFilePath, final ProgressCallback<DeleteObjectRequest, DeleteObjectResult> progressCallback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                asyncDelectObjectFile(uploadFilePath, progressCallback);
            }
        }).start();
    }

    public void delete(String key) {
        try {
            oss.deleteObject(new DeleteObjectRequest(testBucket, key));
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (ServiceException e) {
            e.printStackTrace();
        }
    }

    private String index = "";
    private String width = "";
    private String height = "";


    private String mimeType = "";

    private void asyncPutObjectFromLocalFile(String uploadObject, String uploadFilePath, final ProgressCallback<PutObjectRequest, PutObjectResult> progressCallback) {

        //拼接路径
        //命名方式：日期+随机数
        final String currentTime = String.valueOf(System.currentTimeMillis() / 1000) + getNumLargeSmallLetter(5);
        String hh = uploadFilePath.substring(uploadFilePath.lastIndexOf("."), uploadFilePath.length());
        final String key;
        ObjectMetadata metadata = null;


        mimeType = getMimeType(new File(uploadFilePath));

        if (!mimeType.startsWith("video")) {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(uploadFilePath);
                Bitmap bitmap = BitmapFactory.decodeStream(fis);
                width = "w=" + bitmap.getWidth();
                height = "?h=" + bitmap.getHeight();
                Log.i(">>>width ", "" + width);
                Log.i(">>>height ", "" + height);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

        }


        if (hh.equals(".mp4")) {
            key = uploadObject + "/" + currentTime + hh;
            metadata = new ObjectMetadata();
            metadata.setContentType("video/mp4");
        } else if (hh.equals(".png")) {
            key = uploadObject + "/" + currentTime + ".png";
        } else if (hh.equals(".gif")) {
            key = uploadObject + "/" + currentTime + ".gif";
        } else {
            key = uploadObject + "/" + currentTime + ".jpg";
        }

        // 构造上传请求
        PutObjectRequest put = new PutObjectRequest(testBucket, key, uploadFilePath);
        if (metadata != null) {
            put.setMetadata(metadata);
        }

        // 异步上传时可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                progressCallback.onProgress(request, currentSize, totalSize);
            }
        });
        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                String url = "";
                if (!mimeType.startsWith("video")) {
                    url = oss.presignPublicObjectURL(testBucket, key) + height + width;
                } else {
                    url = oss.presignPublicObjectURL(testBucket, key);
                }


                //BUCKETNAME名字和文件名字。一定要在异步上传完成之后调用。
                Log.e("tenda", "OSSSuccess:" + url);
                progressCallback.onSuccess(request, result, url);
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientException, ServiceException serviceException) {
                progressCallback.onFailure(request, clientException, serviceException);
                // request exception
                if (clientException != null) {
                    // client side exception,  such as network exception
                    clientException.printStackTrace();
                }
                if (serviceException != null) {
                    // service side exception
                    OSSLog.logError("ErrorCode", serviceException.getErrorCode());
                    OSSLog.logError("RequestId", serviceException.getRequestId());
                    OSSLog.logError("HostId", serviceException.getHostId());
                    OSSLog.logError("RawMessage", serviceException.getRawMessage());
                }
            }
        });
    }
    private void asyncPutObjectFromLocalFile2(String uploadObject, String uploadFilePath, int position, final ProgressCallback2<PutObjectRequest, PutObjectResult> progressCallback) {

        //拼接路径
        //命名方式：日期+随机数
        try {
            final String currentTime = String.valueOf(System.currentTimeMillis() / 1000) + getNumLargeSmallLetter(5);
            String hh = uploadFilePath.substring(uploadFilePath.lastIndexOf("."), uploadFilePath.length());
            final String key;
            ObjectMetadata metadata = null;
            if (hh.equals(".mp4")) {
                key = uploadObject + "/" + currentTime + hh;
                metadata = new ObjectMetadata();
                metadata.setContentType("video/mp4");
            } else if (hh.equals(".png")) {
                key = uploadObject + "/" + currentTime + ".png";
            } else if (hh.equals(".gif")) {
//            key = uploadObject + "/" + currentTime + ".gif";
                key = uploadObject + "/" + currentTime + ".jpg";
            } else {
                key = uploadObject + "/" + currentTime + ".jpg";
            }

            // 构造上传请求
            PutObjectRequest put = new PutObjectRequest(testBucket, key, uploadFilePath);
            if (metadata != null) {
                put.setMetadata(metadata);
            }

            // 异步上传时可以设置进度回调
            put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
                @Override
                public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                    progressCallback.onProgress(request, currentSize, totalSize);
                }
            });
            OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                @Override
                public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                    String url = "";
                    if (!mimeType.startsWith("video")) {
                        url = oss.presignPublicObjectURL(testBucket, key) + height + width;
                    } else {
                        url = oss.presignPublicObjectURL(testBucket, key);
                    }
                    //BUCKETNAME名字和文件名字。一定要在异步上传完成之后调用。
                    Log.e("tenda", "OSSSuccess:" + url);
                    progressCallback.onSuccess2(request, result, url, position);
                }

                @Override
                public void onFailure(PutObjectRequest request, ClientException clientException, ServiceException serviceException) {
                    progressCallback.onFailure(request, clientException, serviceException);
                    // request exception
                    if (clientException != null) {
                        // client side exception,  such as network exception
                        clientException.printStackTrace();
                    }
                    if (serviceException != null) {
                        // service side exception
                        OSSLog.logError("ErrorCode", serviceException.getErrorCode());
                        OSSLog.logError("RequestId", serviceException.getRequestId());
                        OSSLog.logError("HostId", serviceException.getHostId());
                        OSSLog.logError("RawMessage", serviceException.getRawMessage());
                    }
                }
            });
        }catch (Exception e){

        }

    }


    private void asyncDelectObjectFile(String uploadFilePath, final ProgressCallback<DeleteObjectRequest, DeleteObjectResult> progressCallback) {


        //去掉第一个“/”
        if (uploadFilePath.length() > 0) {
            uploadFilePath = uploadFilePath.substring(1, uploadFilePath.length());
        }


        // 创建删除请求。
        // 填写Bucket名称和Object完整路径。Object完整路径中不能包含Bucket名称。
        DeleteObjectRequest delete = new DeleteObjectRequest(testBucket, uploadFilePath);
        // 异步删除。
        OSSAsyncTask deleteTask = oss.asyncDeleteObject(delete, new OSSCompletedCallback<DeleteObjectRequest, DeleteObjectResult>() {
            @Override
            public void onSuccess(DeleteObjectRequest request, DeleteObjectResult result) {
                Log.d("asyncDeleteObject", "success!");
                progressCallback.onSuccess(request, result, "");
            }

            @Override
            public void onFailure(DeleteObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                progressCallback.onFailure(request, clientExcepion, serviceException);
                // 请求异常。
                if (clientExcepion != null) {
                    // 客户端异常，例如网络异常等。
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务端异常。
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                }
            }
        });
    }

    /**
     * 数字与大小写字母混编字符串
     *
     * @param size
     * @return
     */
    private String getNumLargeSmallLetter(int size) {
        StringBuffer buffer = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < size; i++) {
            if (random.nextInt(2) % 2 == 0) {//字母
                if (random.nextInt(2) % 2 == 0) {
                    buffer.append((char) (random.nextInt(27) + 'A'));
                } else {
                    buffer.append((char) (random.nextInt(27) + 'a'));
                }
            } else {//数字
                buffer.append(random.nextInt(10));
            }
        }
        return buffer.toString();
    }

    public static String getMimeType(File file) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String type = fileNameMap.getContentTypeFor(file.getName());
        return type;
    }

}
